package com.cubeofnine.sugar;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;

import com.cubeofnine.sugar.business.AccountsBusiness;
import com.cubeofnine.sugar.business.ContactsBusiness;
import com.cubeofnine.sugar.inf.OptionalInterface;
import com.cubeofnine.sugar.service.element.EntryListResult;
import com.cubeofnine.sugar.service.element.EntryResult;
import com.cubeofnine.sugar.service.element.EntryValue;
import com.cubeofnine.sugar.service.element.NameValue;
import com.cubeofnine.utils.ActivityParams;
import com.cubeofnine.utils.StringUtils;
import com.cubeofnine.utils.Validate;

public class FunctionContactsAddActivity extends ActivityImpt implements
		OptionalInterface {
	private static ContactsBusiness contactsBusiness = null;
	private static EntryListResult entryListResult = new EntryListResult();
	private static int rowPerLoad = 20;

	private static Spinner accountsSpinner = null;
	private static String[] accountsIds = null;
	// private static String accountsId = "";

	private static EditText firstName = null;
	private static EditText lastName = null;
	private static EditText email = null;
	private static ImageView saveButton = null;

	// Thread and Handler Variables
	private static Handler handler;
	private Thread thread;

	private static Context context = null;
	private static String contactId = "";
	private static String fixAccountId = null;

	public String getClassName() {
		return FunctionContactsAddActivity.class.getName();
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		Log.i(getClassName(), "onCreate() : Start");

		super.onCreate(savedInstanceState);
		setContentView(R.layout.function_contacts_add);

		context = this;

		TextView headerTitle = (TextView) findViewById(R.id.header_title);
		headerTitle.setText(R.string.function_contacts);

		firstName = (EditText) findViewById(R.id.text_first_name);
		lastName = (EditText) findViewById(R.id.text_last_name);
		email = (EditText) findViewById(R.id.text_email);

		saveButton = (ImageView) findViewById(R.id.header_save);
		saveButton.setVisibility(View.INVISIBLE);

		try {
			fixAccountId = this.getIntentParams().getString(
					ContentDetailActivity.ACCOUNT_ID);
		} catch (Exception e) {
			fixAccountId = null;
		}

		// alertMessage("fixAccountId = " + fixAccountId, true);
		Log.d(getClassName(), "fixAccountId = " + fixAccountId);

		accountsSpinner = (Spinner) findViewById(R.id.dropdown_accounts);

		try {
			boolean isOnline = isOnline();

			Log.d(getClassName(), "isOnline = " + isOnline);
			if (isOnline) {
				// Create a handler to update the UI
				handler = new Handler();

				// Check if the thread is already running
				thread = (Thread) getLastNonConfigurationInstance();
				if (thread != null && thread.isAlive()) {
					initProgressDialog(null);
				} else {
					onLoadAccounts();
				}
			} else {
				alertDialog(R.string.msg_no_connection);
			}

		} catch (Exception e) {
			Log.e(getClassName(), "onCreate()", e);
			alertDialog(R.string.msg_application_error);
		}

		Log.i(getClassName(), "onCreate() : End");
	}

	@Override
	public void onDestroy() {
		Log.i(getClassName(), "onDestroy() : Start");

		if (dialog != null && dialog.isShowing()) {
			dialog.dismiss();
			dialog = null;
		}

		Log.i(getClassName(), "onDestroy() : End");
		super.onDestroy();
	}

	@Override
	public void onRestart() {
		super.onRestart();
		Log.d(getClassName(), "onRestart()");
		finish();
	}

	// Save the thread
	@Override
	public Object onRetainNonConfigurationInstance() {
		Log.d(getClassName(), "onRetainNonConfigurationInstance()");
		return thread;
	}

	static public class FunctionContactsAddActivityThread extends Thread {
		public static String getClassName() {
			return FunctionContactsAddActivityThread.class.getName();
		}

		@Override
		public void run() {
			Log.i(getClassName(), "run() : Start");

			try {
				errorMessage = null;
				contactsBusiness = new ContactsBusiness(context);
				// entryListResult
				int offset = 0;
				int resultCount = 0;
				int totalResultCount = 0;

				EntryListResult result = null;

				if (fixAccountId == null || fixAccountId.isEmpty()) {
					do {
						resultCount = 0;
						result = contactsBusiness.getEntryList(
								ContactsBusiness.MODULE_ACCOUNTS, "",
								AccountsBusiness.ACCOUNTS_ORDER_BY_NAME,
								offset, null, rowPerLoad, 0);
						if (result != null) {
							offset = result.getNextOffset();
							resultCount = result.getResultCount();
							if (resultCount > 0) {
								totalResultCount += resultCount;
								entryListResult
										.setResultCount(totalResultCount);
								entryListResult.getEntryList().putAll(
										result.getEntryList());
							}
						}
					} while (resultCount > 0);
				} else {
					EntryResult entry = contactsBusiness.getEntry(
							ContactsBusiness.MODULE_ACCOUNTS, fixAccountId,
							null);
					if (entry != null) {
						int size = entry.getEntryList().size();
						entryListResult.setResultCount(size);
						entryListResult.setEntryList(entry.getEntryList());
					}
				}
			} catch (Exception e) {
				Log.e(getClassName(), "Connection Error", e);
				errorMessage = context.getString(R.string.msg_connection_error);
			} finally {
				Log.d(getClassName(), "Finally");
				handler.post(new FunctionContactsAddActivityRunnable());
			}

			Log.i(getClassName(), "run() : End");
		}

	}

	static public class FunctionContactsAddActivityRunnable implements Runnable {
		public static String getClassName() {
			return FunctionContactsAddActivityRunnable.class.getName();
		}

		public void run() {
			Log.i(getClassName(), "run() : Start");
			Log.d(getClassName(), "errorMessage = " + errorMessage);

			if (errorMessage != null && !"".equals(errorMessage.trim())) {
				((ActivityImpt) context).alertDialog(errorMessage);
			} else {
				((FunctionContactsAddActivity) context).genContent();
			}

			dialog.dismiss();

			Log.i(getClassName(), "run() : End");
		}
	}

	static public class SaveThread extends Thread {
		public static String getClassName() {
			return SaveThread.class.getName();
		}

		@Override
		public void run() {
			Log.i(getClassName(), "run() : Start");
			try {
				errorMessage = null;
				String firstNameValue = firstName.getText().toString().trim();
				String lastNameValue = lastName.getText().toString().trim();
				String emailValue = email.getText().toString().trim();
				String accountsId = accountsIds[accountsSpinner
						.getSelectedItemPosition()];

				firstNameValue = StringUtils.encodeToken(firstNameValue);
				lastNameValue = StringUtils.encodeToken(lastNameValue);

				contactId = contactsBusiness.createContact(firstNameValue,
						lastNameValue, emailValue, accountsId);
			} catch (Exception e) {
				Log.e(getClassName(), "Connection Error", e);
				errorMessage = context.getString(R.string.msg_connection_error);
			} finally {
				Log.d(getClassName(), "Finally");
				handler.post(new SaveRunnable());
			}
			Log.i(getClassName(), "run() : End");
		}
	}

	static public class SaveRunnable implements Runnable {
		public static String getClassName() {
			return SaveRunnable.class.getName();
		}

		public void run() {
			Log.i(getClassName(), "run() : Start");
			Log.d(getClassName(), "errorMessage = " + errorMessage);

			if (errorMessage != null && !"".equals(errorMessage.trim())) {
				((ActivityImpt) context).alertDialog(errorMessage);
			} else {
				if (contactId != null && !contactId.isEmpty()) {
					((ActivityImpt) context).alertMessage(
							R.string.msg_successfully, true);

					List<ActivityParams> params = new Vector<ActivityParams>();
					params.add(new ActivityParams(
							ContentDetailActivity.MODULE_NAME,
							ContactsBusiness.MODULE_CONTACTS));
					params.add(new ActivityParams(
							ContentDetailActivity.MODULE_ID, contactId));
					gotoActivity(ContentDetailActivity.class, params);
				}
			}

			dialog.dismiss();

			Log.i(getClassName(), "run() : End");
		}
	}

	public void onLoadAccounts() {
		Log.i(getClassName(), "doClickContacts() : Start");

		initProgressDialog(null);

		thread = new FunctionContactsAddActivityThread();
		thread.start();

		Log.i(getClassName(), "doClickContacts() : End");
	}

	public void doSave() {

		String firstNameValue = firstName.getText().toString().trim();
		String lastNameValue = lastName.getText().toString().trim();
		String emailValue = email.getText().toString().trim();

		if (firstNameValue.isEmpty()) {
			alertDialog(R.string.msg_first_name_empty);
		} else if (lastNameValue.isEmpty()) {
			alertDialog(R.string.msg_last_name_empty);
		} else if (emailValue.isEmpty()) {
			alertDialog(R.string.msg_email_empty);
		} else if (!Validate.isValidEmail(emailValue)) {
			alertDialog(R.string.msg_email_invalid);
		} else {
			initProgressDialog("Processing...");
			thread = new SaveThread();
			thread.start();
		}
	}

	public void genContent() {
		if (entryListResult != null && entryListResult.getResultCount() > 0) {
			saveButton.setVisibility(View.VISIBLE);

			String id = "";
			String name = "";

			EntryValue entry = null;

			Map entryList = entryListResult.getEntryList();
			Set entrySet = entryList.keySet();
			Iterator entryIter = entrySet.iterator();

			String[] accountsName = new String[entryList.size()];
			accountsIds = new String[entryList.size()];

			int i = 0;
			while (entryIter.hasNext()) {
				entry = (EntryValue) entryList.get(((String) entryIter.next()));
				id = entry.getId();
				name = (i + 1)
						+ ".) "
						+ ((NameValue) entry.getNameValueList().get("name"))
								.getValue();

				accountsIds[i] = id;
				accountsName[i++] = name;
			}

			ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
					android.R.layout.simple_spinner_item, accountsName);
			arrayAdapter
					.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
			accountsSpinner.setAdapter(arrayAdapter);
		} else {
			AlertDialog.Builder adb = new AlertDialog.Builder(context);

			adb.setIcon(android.R.drawable.ic_dialog_alert);
			adb.setTitle(R.string.function_accounts);
			adb.setMessage(R.string.msg_account_list_null);
			adb.setPositiveButton(R.string.button_ok,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							gotoActivity(FunctionAccountsAddActivity.class);
						}
					});
			adb.show();
		}
	}

	public void onClickOptionalButton(View view) {
		view.startAnimation(AnimationUtils.loadAnimation(this,
				R.anim.image_click));
		// TODO Auto-generated method stub
		doSave();
	}

	public void onClickSearchButton(View view) {
		view.startAnimation(AnimationUtils.loadAnimation(this,
				R.anim.image_click));
		// TODO Auto-generated method stub

	}
}
